from __future__ import with_statement
from google.appengine.ext import blobstore
from google.appengine.api import files
import mimetypes
from django.core.cache import cache
from django.contrib.auth.forms import UserCreationForm
from django.views.generic.simple import direct_to_template
from django.http import HttpResponseRedirect
from django.http import HttpResponse
from datetime import date, time, datetime 
from django.core.exceptions import ObjectDoesNotExist
from django.core.exceptions import MultipleObjectsReturned
from django.views.generic.simple import direct_to_template
from matchmeapp.forms import CreateGreetingForm
from matchmeapp.models import Greeting
from matchmeapp.models import Tag
from matchmeapp.models import Post
from matchmeapp.models import Like
from matchmeapp.models import Comment
from matchmeapp.models import Alert
from matchmeapp.models import Friend
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from django.core.files.base import ContentFile
import logging
from google.appengine.ext import db


MEMCACHE_GREETINGS = 'greetings'
DATE_FORMAT = "%Y-%m-%d" 
TIME_FORMAT = "%H-%M-%S"

def list_greetings(request):
    greetings = cache.get(MEMCACHE_GREETINGS)
    if greetings is None:
        greetings = Greeting.objects.all().order_by('-date')[:10]
        cache.add(MEMCACHE_GREETINGS, greetings)
    return direct_to_template(request, 'matchmeapp/index.html',
                              {'greetings': greetings,
                               'form': CreateGreetingForm()})

def create_greeting(request):
    if request.method == 'POST':
        form = CreateGreetingForm(request.POST)
        if form.is_valid():
            greeting = form.save(commit=False)
            greeting.author = request.user
            greeting.save()
            cache.delete(MEMCACHE_GREETINGS)
    return HttpResponseRedirect('/matchmeapp/')

def create_new_user(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            user = form.save(commit=False)
            # user must be active for login to work
            user.is_active = True
            user.save()
            return HttpResponseRedirect('/matchmeapp/')
    else:
        form = UserCreationForm()
    return direct_to_template(request, 'matchmeapp/user_create_form.html',
        {'form': form})
		
def create_matchme_user(request):
	username = request.POST.get('username', '')
	password = request.POST.get('password', '')
	email = request.POST.get('email', '')
	firstName = request.POST.get('firstname', '')
	lastName = request.POST.get('lastname', '')
	if User.objects.filter(username=username).count() is not 0:
		return  HttpResponse("failed")	
		
	if User.objects.filter(email=email).all().count() is not 0:
		return  HttpResponse("failed")
		
	user = User.objects.create_user(username,  email, password);
	
	try:
		user = User.objects.get(username=username)
		user.first_name = firstName
		user.last_name = lastName
		user.save()
		returnstr = "success"
	except (ObjectDoesNotExist, MultipleObjectsReturned), e:
		returnstr = "failed"
	finally:
		html = returnstr
	return  HttpResponse(html)	
	
	
def mm_login(request):
	username = request.POST.get('username', '')
	password = request.POST.get('password', '')
	user = authenticate(username=username, password=password)
	if user is not None and user.is_active:
		# Correct password, and the user is marked "active"
		login(request, user)
		returnstr = "success"	
	else:
		# Show an error page
		returnstr = "failed"
		
	#res = HttpResponse(returnstr).set_cookie("sessionid", );
	return HttpResponse(returnstr)

def mm_logout(request):
	logout(request)
	return HttpResponse("")
        
def list_posts(request, user):
    if request.user.is_authenticated():
        posts = Post.objects.filter(userid1=user)
        html = "<html><body>Hello World.</body></html>" 
        return  HttpResponse(html)
    else:
       return HttpResponse("failed: user auth")	
	
	
def find_friends(request, newusername):
	returnstr = "failed: user auth"
	if request.user.is_authenticated():
		friends = User.objects.filter(username=newusername)
		returnstr = ""
		for friend in friends:
			if ( friend.username == request.user.username ):
				returnstr = returnstr
			else :
				returnstr = returnstr + friend.username + ";"
	return  HttpResponse(returnstr)


def get_recent(request, order):
	if request.user.is_authenticated():
		posts = Post.objects.filter(userid1=request.user, status='C')[(order * 10):(int(order * 10) + 9)]
		str = ""
		for post in posts:
			if post.status.endswith("C"):
				str = str + "%d" % post.id + ";"
				str = str + post.userid1.username + ";";
				str = str + post.userid2.username + ";";
				#str = str + post.pic1 + ";";
				str = str + post.location1 + ";";
				str = str + post.location2 + ";";
				str = str + post.status + ";";
				str = str + post.time1.strftime("%s-%s" % (DATE_FORMAT, TIME_FORMAT)) + ";";
				str = str + post.time2.strftime("%s-%s" % (DATE_FORMAT, TIME_FORMAT)) + ";";
				str = str + post.description1 + ";";
				str = str + post.description2 + ";";
		return  HttpResponse(str)
	else:
		return HttpResponse("failed: user auth")
		
def get_recent_latest(request, date1):
	if request.user.is_authenticated():
		str = ""
		a = date1.split('-')
		posts = Post.objects.filter(userid1=request.user, status='C').filter(time2__gt=datetime.combine(date(int(a[0]),int(a[1]),int(a[2])), time(int(a[3]), int(a[4]),int(a[5])))).order_by('time2')[(0* 10):(int(0 * 10) + 9)]
		str = ""
		for post in posts:
			if post.status.endswith("C"):
				str = str + "%d" % post.id + ";"
				str = str + post.userid1.username + ";";
				str = str + post.userid2.username + ";";
				#str = str + post.pic1 + ";";
				str = str + post.location1 + ";";
				str = str + post.location2 + ";";
				str = str + post.status + ";";
				str = str + post.time1.strftime("%s-%s" % (DATE_FORMAT, TIME_FORMAT)) + ";";
				str = str + post.time2.strftime("%s-%s" % (DATE_FORMAT, TIME_FORMAT)) + ";";
				str = str + post.description1 + ";";
				str = str + post.description2 + ";";
		return  HttpResponse(str)
	else:
		return HttpResponse("failed: user auth")
	  
def get_relationship(request, newuserid, order):
	if request.user.is_authenticated():
		try:
			user1 = User.objects.filter(username=newuserid)
			posts = Post.objects.filter(userid1=user1, userid2=request.user, status='C')[(order * 10):(int(order * 10) + 9)]
			str = ""
			for post in posts:
				if post.status.endswith("C"):
					str = str + "%d" % post.id + ";"
					str = str + post.userid1.username + ";";
					str = str + post.userid2.username + ";";
					#str = str + post.pic1 + ";";
					str = str + post.location1 + ";";
					str = str + post.location2 + ";";
					str = str + post.status + ";";
					str = str + post.time1.strftime("%s-%s" % (DATE_FORMAT, TIME_FORMAT)) + ";";
					str = str + post.time2.strftime("%s-%s" % (DATE_FORMAT, TIME_FORMAT)) + ";";
					str = str + post.description1 + ";";
					str = str + post.description2 + ";";
		except (ObjectDoesNotExist, MultipleObjectsReturned), e:
			str = "failed"
		finally:
			return  HttpResponse(str)
	else:
		return HttpResponse("failed: user auth")
				
def get_timeline(request, order):
	if request.user.is_authenticated():
		try:
			posts = Post.objects.filter(userid1=request.user, status='C').order_by('time1')[(order * 10):(int(order * 10) + 9)]
			str = ""
			for post in posts:
				if post.status.endswith("C"):
					str = str + "%d" % post.id + ";"
					str = str + post.userid1.username + ";";
					str = str + post.userid2.username + ";";
					#str = str + post.pic1 + ";";
					str = str + post.location1 + ";";
					str = str + post.location2 + ";";
					str = str + post.status + ";";
					str = str + post.time1.strftime("%s-%s" % (DATE_FORMAT, TIME_FORMAT)) + ";";
					str = str + post.time2.strftime("%s-%s" % (DATE_FORMAT, TIME_FORMAT)) + ";";
					str = str + post.description1 + ";";
					str = str + post.description2 + ";";
			posts = Post.objects.filter(userid2=request.user, status='C').order_by('time2')[(order * 10):(int(order * 10) + 9)]
			#posts = orderpost.reverse()
			for post in posts:
				str = str + "%d" % post.id + ";"
				str = str + post.userid1.username + ";";
				str = str + post.userid2.username + ";";
				#str = str + post.pic1 + ";";
				str = str + post.location1 + ";";
				str = str + post.location2 + ";";
				str = str + post.status + ";";
				str = str + post.time1.strftime("%s-%s" % (DATE_FORMAT, TIME_FORMAT)) + ";";
				str = str + post.time2.strftime("%s-%s" % (DATE_FORMAT, TIME_FORMAT)) + ";";
				str = str + post.description1 + ";";
				str = str + post.description2 + ";";
		except (ObjectDoesNotExist, MultipleObjectsReturned), e:
			str = "failed"
		finally:
			return  HttpResponse(str)
	else:
		return HttpResponse("failed: user auth")
		
def get_timeline_latest(request, date1):
	if request.user.is_authenticated():
		try:
			str = ""
			a = date1.split('-')
			posts = Post.objects.filter(userid1=request.user , status='C').filter(time2__gt=datetime.combine(date(int(a[0]),int(a[1]),int(a[2])), time(int(a[3]), int(a[4]), int(a[5])))).order_by('time2')[(0* 10):(int(0 * 10) + 9)]
			str = ""
			for post in posts:
				if post.status.endswith("C"):
					str = str + "%d" % post.id + ";"
					str = str + post.userid1.username + ";";
					str = str + post.userid2.username + ";";
					#str = str + post.pic1 + ";";
					str = str + post.location1 + ";";
					str = str + post.location2 + ";";
					str = str + post.status + ";";
					str = str + post.time1.strftime("%s-%s" % (DATE_FORMAT, TIME_FORMAT)) + ";";
					str = str + post.time2.strftime("%s-%s" % (DATE_FORMAT, TIME_FORMAT)) + ";";
					str = str + post.description1 + ";";
					str = str + post.description2 + ";";
		except (ObjectDoesNotExist, MultipleObjectsReturned), e:
			str = "failed %s" % e
		finally:
			return  HttpResponse(str)
	else:
		return HttpResponse("failed: user auth")
	
def create_post(request):
    if request.user.is_authenticated():
		user2 = User.objects.get(username=request.POST.get('userid2',''))
		#file_content = ContentFile(request.FILES['data'].read())
		p = Post(userid1=request.user,location1=request.POST.get('location1',''),description1=request.POST.get('description1',''),userid2=user2,status='P')
		p.time2 = datetime.now()
		p.save()
		#p.pic1.save(request.FILES['data'].name, file_content)
		#file_name = files.blobstore.create(mime_type=mimetypes.guess_type(request.FILES['data'].name))
		content_type = 'multipart/form-data'
		# Create the file
		file_name = files.blobstore.create(mime_type=content_type)

		file = request.FILES['file']
		
		## Open the file and write to it
		#logger.debug("%d" % f.size)

		with files.open(file_name, 'a') as f:
			f.write(file.read())
			
		files.finalize(file_name)
		blob_key = files.blobstore.get_blob_key(file_name)
		p.pic1=str(blob_key)
		p.save()
		returnstr = "failed";
		try:
			# check if the post is successfully saved 
			mypost = Post.objects.get(id=p.id)
			
			# add alert object to notify userid2
			#userid1 is the requested friend
			#userid2 is the requester
			#typeid is the postID
			a = Alert(userid1=user2, userid2=request.user, type='M',typeid=p.id)
			a.save()
			try:
				mytag = Alert.objects.get(id=a.id)
				return HttpResponse("%d;" % p.id )
			except (ObjectDoesNotExist, MultipleObjectsReturned), e:
				return HttpResponse("failed")
		except (ObjectDoesNotExist, MultipleObjectsReturned), e:
			return HttpResponse("failed")
    else:
       return HttpResponse("failed: user auth")
	   
#def update_post(request):
#    if request.user.is_authenticated():
#		p = Post(userid1=request.user,location1=newlocation,pic1=newpic,description1=newdescription,userid2=newuserid2)
#		p.save
#		returnstr = "failed";
#		try:
#			mypost = Post.objects.get(userid1=request.user.username, userid2=newuserid2)
#			returnstr = "passed"
#		except (ObjectDoesNotExist, MultipleObjectsReturned), e:
#			returnstr = "failed"
#		finally:
#			html = returnstr
#		return HttpResponse(html)
#    else:
#       return HttpResponse("failed: user auth")
		
def get_post(request, postid):
    if request.user.is_authenticated():
		str = ""
		try:
			post = Post.objects.get(id=postid)
			str = str + post.userid1.username + ";";
			str = str + post.userid2.username + ";";
			#str = str + post.pic1 + ";";
			str = str + post.location1 + ";";
			str = str + post.location2 + ";";
			str = str + post.status + ";";
			str = str + post.time1 + ";";
			str = str + post.time2 + ";";
			str = str + post.description1 + ";";
			str = str + post.description2 + ";";
		except (ObjectDoesNotExist, MultipleObjectsReturned), e:
			str = "failed"
		finally:
			return  HttpResponse(str)
    else:
       return HttpResponse("failed: user auth")	
	   
def get_image(request, postid):
	if request.user.is_authenticated():
		post = Post.objects.get(id=postid)
		blob_key = post.pic1
		blob_info = blobstore.BlobInfo.get(blob_key)
		blob_file_size = blob_info.size
		blob_content_type = blob_info.content_type
		
		blob_reader = blobstore.BlobReader(blob_key)
		blob_reader = blobstore.BlobReader(blob_key, buffer_size=1048576)
		blob_reader = blobstore.BlobReader(blob_key, position=0)
		value = blob_reader.read()
		
		return HttpResponse(value, mimetype=blob_content_type)
	else:
		return HttpResponse("failed: user auth")
	
def show_image(request, postid):
	post = Post.objects.get(id=postid)
	blob_key = post.pic1
	blob_info = blobstore.BlobInfo.get(blob_key)
	blob_file_size = blob_info.size
	blob_content_type = blob_info.content_type

	blob_reader = blobstore.BlobReader(blob_key)
	blob_reader = blobstore.BlobReader(blob_key, buffer_size=1048576)
	blob_reader = blobstore.BlobReader(blob_key, position=0)
	value = blob_reader.read()
	
	#self.response.headers['Content-Type'] = 'image/png'
	#self.response.out.write(value)

	return HttpResponse(value, mimetype="image/png")

def remove_post(request, newpostid):
    if request.user.is_authenticated():
        try:
            mypost = Post.objects.get(id=newpostid)
            mypost.delete()
            returnstr = "passed"
        except (ObjectDoesNotExist, MultipleObjectsReturned), e:
            returnstr = "failed"
        finally:
            html = returnstr
        return  HttpResponse(html)
    else:
       return HttpResponse("failed: user auth")	

def get_alerts(request):
    if request.user.is_authenticated():
        str = ""
        #alerts = Alert.objects.filter(userid1=request.user.username)
        #for alert in alerts:
            #str = str + alert.userid2.username + ";"
            #str = str + alert.type + ";"
            #str = str + alert.typeid + ";"
        #userid2 is the requester
        alerts = Alert.objects.filter(userid1=request.user)
        for alert in alerts:
			str = str + "%d" % alert.id + ";"
			str = str + alert.userid2.username + ";"
			str = str + "%c" % alert.type + ";"
			str = str + "%d" % alert.typeid + ";"
			str = str + alert.created_on.strftime("%s-%s" % (DATE_FORMAT, TIME_FORMAT)) + ";";
        html = str
        return HttpResponse(html)
    else:
       return HttpResponse("failed: user auth")	

def get_alerts_latest(request, date1):
	if request.user.is_authenticated():
		str = ""
		a = date1.split('-')
        #alerts = Alert.objects.filter(userid1=request.user.username)
        #for alert in alerts:
            #str = str + alert.userid2.username + ";"
            #str = str + alert.type + ";"
            #str = str + alert.typeid + ";"
        #userid2 is the requester
		alerts = Alert.objects.filter(userid1=request.user).filter(created_on__gt=datetime.combine(date(int(a[0]),int(a[1]),int(a[2])), time(int(a[3]), int(a[4]), int(a[5]))))
		for alert in alerts:
			str = str + "%d" % alert.id + ";"
			str = str + alert.userid2.username + ";"
			str = str + "%c" % alert.type + ";"
			str = str + "%d" % alert.typeid + ";"
			str = str + alert.created_on.strftime("%s-%s" % (DATE_FORMAT, TIME_FORMAT)) + ";";
		html = str
		return HttpResponse(html)
	else:
		return HttpResponse("failed: user auth")	

def accept_matchme(request):
	if request.user.is_authenticated():
		returnstr = "success"
		try:
			#get Post obj
			p = Post.objects.get(id=request.POST.get('postid',''))
			p.location2 = request.POST.get('location2','')
			p.description2 = request.POST.get('description2','')
			p.time2 = datetime.now()
			p.status = 'C'
			p.save()
			
			
			content_type = 'multipart/form-data'
			# Create the file
			file_name = files.blobstore.create(mime_type=content_type)

			file = request.FILES['file']
		
			## Open the file and write to it
			#logger.debug("%d" % f.size)

			with files.open(file_name, 'a') as f:
				f.write(file.read())
			
			files.finalize(file_name)
			blob_key = files.blobstore.get_blob_key(file_name)
			p.pic1=str(blob_key)
			p.save()
			
			alert = Alert.objects.get(id=request.POST.get('alertid',''))
			alert.delete()
			returnstr = "success"
		except(ObjectDoesNotExist, MultipleObjectsReturned), e:
			returnstr = "failed"
		finally:
			html = returnstr
		return HttpResponse(html)
	else:
		return HttpResponse("failed: user auth")	
    
def deny_matchme(request, newalertid):
	if request.user.is_authenticated():
		try:
			returnstr = ""
			alert = Alert.objects.get(id = newalertid)
			p = Post.objects.get(id=alert.typeid)
			p.delete()
			alert.delete()
            
			returnstr = "success"
		except (ObjectDoesNotExist, MultipleObjectsReturned), e:
			returnstr = "failed"
		finally:
			html = returnstr
			return  HttpResponse(html)
	else:
		return HttpResponse("failed: user auth")	
    
def get_friends(request):
	if request.user.is_authenticated():
		friends = Friend.objects.filter(userid1=request.user)
		str = ""
		for friend in friends:
			str = str + friend.userid2.username + ";";

		friends = Friend.objects.filter(userid2=request.user)
		for friend in friends:
			str = str + friend.userid1.username + ";";
		html =  str
		return  HttpResponse(html)
	else:
		return HttpResponse("failed: user auth")	
    
def request_friend(request, newuserid1):
	if request.user.is_authenticated():
		user1 = User.objects.get(username=newuserid1)
		#userid1 is the requested friend
		#userid2 is the requester
		#typeid is irrelevant in this case
		if  Alert.objects.filter(userid1=user1, userid2=request.user, type='F').count() is not 0:
			return HttpResponse("failed")	
		a = Alert(userid1=user1, userid2=request.user, type='F',typeid=0)
		a.save()
		try:
			mytag = Alert.objects.get(id=a.id)
			returnstr = "success"
		except (ObjectDoesNotExist, MultipleObjectsReturned), e:
			returnstr = "failed"
		finally:
			html = returnstr

		return  HttpResponse(html)
	else:
		return HttpResponse("failed: user auth")	
    
def accept_friend(request, newalertid):
    if request.user.is_authenticated():
        try:
            #get Alert info
            myalert = Alert.objects.get(id=newalertid)
            #insert to Friend
            f = Friend(userid1=myalert.userid1,userid2=myalert.userid2)
            f.save()
            #remove Alert
            myalert.delete()
            
            returnstr = "success"
        except (ObjectDoesNotExist, MultipleObjectsReturned), e:
            returnstr = "failed"
        finally:
            html = returnstr
        return  HttpResponse(html)
    else:
       return HttpResponse("failed: user auth")	
   
def deny_friend(request, newalertid):
    if request.user.is_authenticated():
        try:
            myalert = Alert.objects.get(id=newalertid)
            myalert.delete()
            returnstr = "success"
        except (ObjectDoesNotExist, MultipleObjectsReturned), e:
            returnstr = "failed"
        finally:
            html = returnstr
        return  HttpResponse(html)
    else:
       return HttpResponse("failed: user auth")	
       
def add_comment(request, newpostid, newuserid, newdescription):
	if request.user.is_authenticated():
		user1 = User.objects.get(username=newuserid)
		post1 = Post.objects.get(id=newpostid)
		t = Comment(userid=user1, postid=post1, description=newdescription)
		t.save()
		try:
			mycomment = Comment.objects.get(id=t.id)
			returnstr = "passed"
		except (ObjectDoesNotExist, MultipleObjectsReturned), e:
			returnstr = "failed"
		return  HttpResponse(returnstr)
	else:
		return HttpResponse("failed: user auth")	
		
def get_comments(request, newpostid):
	if request.user.is_authenticated():
		post1 = Post.objects.get(id=newpostid)
		comments = Comment.objects.filter(postid=post1)
		str = ""
		for comm in comments:
			str = str + comm.userid.username + ";"
			str = str + comm.description + ";"
			str = str + comm.time1.strftime("%s-%s" % (DATE_FORMAT, TIME_FORMAT)) + ";";
		return HttpResponse(str)
	else:
		return HttpResponse("failed: user auth")	
       
def add_tag(request, newpostid, newuserid):
    if request.user.is_authenticated():
        t = Tag(userid=newuserid, postid=newpostid)
        t.save()
        try:
            mytag = Tag.objects.get(postid=newpostid,userid=newuserid)
            returnstr = "passed"
        except (ObjectDoesNotExist, MultipleObjectsReturned), e:
            returnstr = "failed"
        finally:
            html = returnstr
        return  HttpResponse(html)
    else:
       return HttpResponse("failed: user auth")	

def get_likes(request, newpostid):
	if request.user.is_authenticated():
		post1 = Post.objects.get(id=newpostid)
		likes = Like.objects.filter(postid=post1)
		str = ""
		for like in likes:
			str = str + like.userid.username + ";"
		return HttpResponse(str)
	else:
		return HttpResponse("failed: user auth")	
	   
def add_like(request, newpostid, newuserid):
	if request.user.is_authenticated():
		post1 = Post.objects.get(id=newpostid)
		user1 = User.objects.get(username=newuserid)
		t = Like(userid=user1, postid=post1)
		t.save()
		try:
			mylike = Like.objects.get(userid=user1, postid=post1)
			returnstr = "passed"
		except (ObjectDoesNotExist, MultipleObjectsReturned), e:
			returnstr = "failed"
		return  HttpResponse(returnstr)
	else:
		return HttpResponse("failed: user auth")	
   
def remove_like(request, newpostid, newuserid):
    if request.user.is_authenticated():
        try:
            mylike = Like.objects.get(userid=newuserid, postid=newpostid)
            mylike.delete()
            returnstr = "passed"
        except (ObjectDoesNotExist, MultipleObjectsReturned), e:
            returnstr = "failed"
        finally:
            html = returnstr
        return  HttpResponse(html)
    else:
       return HttpResponse("failed: user auth")	